package net.entelijan.cobean.tree;

import java.awt.Component;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;

import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.MutableTreeNode;
import javax.swing.tree.TreeNode;

class CobeanTreeNode implements MutableTreeNode, IPathFinderNode {

	private Object model;

	private ITreeLevelDescription desc;

	private List<CobeanTreeNode> children;

	public CobeanTreeNode(Object model, ITreeLevelDescription desc) {
		super();
		this.model = model;
		this.desc = desc;
	}

	@Override
	public void insert(MutableTreeNode child, int index) {
		throw new UnsupportedOperationException("Should never be called");
	}

	@Override
	public void remove(int index) {
		throw new UnsupportedOperationException("Should never be called");

	}

	@Override
	public void remove(MutableTreeNode node) {
		throw new UnsupportedOperationException("Should never be called");
	}

	@Override
	public void removeFromParent() {
		throw new UnsupportedOperationException("Should never be called");
	}

	@Override
	public void setParent(MutableTreeNode newParent) {
		throw new UnsupportedOperationException("Should never be called");
	}

	@Override
	public void setUserObject(Object object) {
		throw new UnsupportedOperationException("Should never be called");
	}

	@SuppressWarnings({ "rawtypes" })
	@Override
	public Enumeration children() {
		throw new UnsupportedOperationException("Should never be called");
	}

	@Override
	public boolean getAllowsChildren() {
		throw new UnsupportedOperationException("Should never be called");
	}

	@Override
	public javax.swing.tree.TreeNode getChildAt(int childIndex) {
		return (TreeNode) getChildren().get(childIndex);
	}

	@Override
	public int getChildCount() {
		return getChildren().size();
	}

	@Override
	public int getIndex(javax.swing.tree.TreeNode node) {
		return getChildren().indexOf(node);
	}

	@Override
	public javax.swing.tree.TreeNode getParent() {
		throw new UnsupportedOperationException("Should never be called");
	}

	@Override
	public boolean isLeaf() {
		return getChildren().isEmpty();
	}

	public List<? extends IPathFinderNode> getChildren() {
		if (this.children == null) {
			ArrayList<CobeanTreeNode> l = new ArrayList<CobeanTreeNode>();
			for (Object cm : this.desc.getChildren(model)) {
				l.add(new CobeanTreeNode(cm, desc.getChildDescription()));
			}
			this.children = l;
		}
		return this.children;
	}

	@Override
	public String toString() {
		return model.toString();
	}

	public Object getModel() {
		return model;
	}

	public void setModel(Object model) {
		this.model = model;
	}

	public ITreeLevelDescription getDesc() {
		return desc;
	}

	public void setDesc(ITreeLevelDescription desc) {
		this.desc = desc;
	}

	public Component getTreeCellRendererComponent(
			DefaultTreeCellRenderer defaultComp, boolean sel, boolean expanded,
			boolean leaf, int row, boolean hasFocus) {
		Component re = this.desc.getTreeCellRendererComponent(this.model, defaultComp, sel, expanded, leaf, row, hasFocus);
		return re;
	}

}
